#pragma once
#include "config.h"

//用于和AGV通信的指令

/*
* 数据帧格式
* Byte 0	帧头
* Byte 1	待呼叫的AGV小车地址，可由拨码开关设置
* Byte 2	呼叫指令码，见通信协议
* Byte 3	呼叫器设备ID，在当前一个呼叫器盒子对应一个工位的情况下，ID=0
* Byte 4	子码，在当前一个呼叫器盒子对应一个工位的情况下，子码由拨码开关设置
* Byte 5	CRC16校验码低字节
* Byte 6	CRC16校验码高字节
*/

typedef enum {
	NO_Indic,      //无动作
	SENDING_Indic, //发送中
	RIGHT_Indic,   //成功应答
	BUSY_Indic,    //繁忙应答
	FAILURE_Indic  //未接受到应答
} Indic;

class AGV_CMD_Class
{
public:
	typedef enum {
		NO_TX,      //无发送动作
		READY_TX,	//准备发送
		WAIT_TX,    //等待发送
		WAIT_ACK,   //等待应答
		SUCCESS_ACK,//接收应答成功
		ERROR_ACK   //未接收到应答
	} CMD_state;

	typedef enum {
		NO_RX,    //无应答
		RIGHT_RX, //接收到成功应答
		BUSY_RX   //接收到繁忙应答
	} RX_state;


	AGV_CMD_Class() = default;
	~AGV_CMD_Class() = default;

	void Init(char frame, char agv_add, char cmd, char subcode, char id = 0);	//计算数据帧校验位
	inline void Set_TX(void) { tx_state = READY_TX; }	//设置准备发送
	inline bool TX_Flag(void) { return tx_state != NO_TX; } //返回是否有发送动作，有发送动作返回true
	void find_cmd(const char *source, int length);       //从接收到的数据中检测应答信号
	int Check(char* &str);	//检查指令状态，返回待发送指令

	Indic indic;
	CMD_state tx_state;

private:
	char right[7];
	char busy[7];

	unsigned char retry;
	unsigned char time_out;

	RX_state rx_state;

	bool find(const char *source, int length, const char *cmd);
};